<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WPF资源翻译工具</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
    <!-- 引入spark-md5库 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/spark-md5/3.0.2/spark-md5.min.js"></script>
</head>
<body class="bg-gray-100 min-h-screen p-6 flex items-center justify-center">
    <div class="w-full bg-white rounded-xl shadow-lg p-6 space-y-6 px-4">
        <!-- 标题 -->
        <div class="flex items-center space-x-3">
            <i class="material-icons text-blue-600 text-3xl">translate</i>
            <h1 class="text-2xl font-bold text-gray-800">WPF资源字典翻译工具</h1>
        </div>

        <!-- 文件上传区域 -->
        <div id="drop-zone" 
             class="border-2 border-dashed border-gray-300 rounded-xl p-8 text-center hover:border-blue-500 transition-colors">
            <input type="file" id="file-input" class="hidden" accept=".xaml">
            <label for="file-input" class="cursor-pointer">
                <i class="material-icons text-4xl text-gray-400">cloud_upload</i>
                <p class="mt-2 text-gray-600">点击选择或拖拽文件到此区域</p>
            </label>
        </div>

        <!-- 资源表格 -->
        <div class="overflow-x-auto rounded-lg border border-gray-200 w-full">
            <table class="min-w-full divide-y divide-gray-200 w-full table-fixed">
                <thead class="bg-gray-50">
                    <tr>
                        <th class="px-4 py-3 text-left text-sm font-medium text-gray-700 w-1/5">Key</th>
                        <th class="px-4 py-3 text-left text-sm font-medium text-gray-700 w-2/5 truncate" title="完整中文内容">原文（中文）</th>
                        <th class="px-4 py-3 text-left text-sm font-medium text-gray-700 w-2/5 truncate" title="完整英文内容">译文（英文）</th>
                    </tr>
                </thead>
                <tbody id="content" class="bg-white divide-y divide-gray-200">
                    <!-- 动态填充数据 -->
                </tbody>
            </table>
        </div>

        <!-- 操作按钮 -->
        <div class="flex justify-end space-x-4">
            <button id="translate-btn" 
                    class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50"
                    disabled>
                <i class="material-icons align-middle">translate</i>
                批量翻译
            </button>
            <button id="export-btn" 
                    class="px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 disabled:opacity-50"
                    disabled>
                <i class="material-icons align-middle">save_alt</i>
                导出文件
            </button>
        </div>

        <!-- Loading 指示器 -->
        <div id="loading-overlay" 
             class="hidden fixed inset-0 bg-black/50 backdrop-blur-sm z-50 flex flex-col items-center justify-center space-y-2">
            <i class="material-icons text-white text-6xl animate-spin">autorenew</i>
            <p class="text-white text-lg font-medium">翻译进行中，请稍候...</p>
        </div>
    </div>

<script>
// 需要替换为您的翻译API密钥

let resources = [];

// 初始化拖拽功能
const dropZone = document.getElementById('drop-zone');
dropZone.addEventListener('dragover', (e) => {
    e.preventDefault();
    dropZone.classList.add('border-blue-500');
});
dropZone.addEventListener('dragleave', () => {
    dropZone.classList.remove('border-blue-500');
});
dropZone.addEventListener('drop', (e) => {
    e.preventDefault();
    dropZone.classList.remove('border-blue-500');
    handleFile(e.dataTransfer.files[0]);
});

// 文件选择处理
document.getElementById('file-input').addEventListener('change', (e) => {
    handleFile(e.target.files[0]);
});

// 处理XAML文件
async function handleFile(file) {
    if (!file.name.endsWith('.xaml')) {
        alert('请选择.xaml文件');
        return;
    }

    const text = await file.text();
    if (!text) {
        alert('文件内容为空');
        return;
    }
    parseXAML(text);
    renderTable();
    toggleButtons(true);
}

/** 解析下面的XAML文件，并提取key 和 value
 * <ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:sys="clr-namespace:System;assembly=mscorlib">
    <sys:String x:Key="MachineTest_TaskGroup_TestInfo_Name_ConST811AH">整机</sys:String>
    </ResourceDictionary>
 */
function parseXAML(xamlText) {
    const parser = new DOMParser();
    const xmlDoc = parser.parseFromString(xamlText, 'text/xml');
    resources = [];
    
    // 检查解析是否成功
    if (xmlDoc.getElementsByTagName('parsererror').length > 0) {
        alert('XAML文件解析错误');
        return;
    }

    // 遍历所有资源
    const resourceElements = xmlDoc.getElementsByTagName('sys:String');
    for (let i = 0; i < resourceElements.length; i++) {
        const resourceElement = resourceElements[i];    
        const key = resourceElement.getAttribute('x:Key');
        // 获取value "整机" 

        const value = resourceElement.textContent.trim();
        // 处理XML命名空间问题
        const systemNamespace = resourceElement.getAttribute('xmlns:sys') || 'clr-namespace:System;assembly=mscorlib';
        resources.push({ 
            key, 
            original: value,
            translated: '',
            modified: false,
            systemNamespace // 保存命名空间信息
        });
    }
}

// 渲染表格
function renderTable() {
    const tbody = document.getElementById('content');
    tbody.innerHTML = '';
    
    resources.forEach((item, index) => {
        const tr = document.createElement('tr');
        tr.innerHTML = `
            <td class="px-4 py-3 text-sm text-gray-700 w-1/5 truncate" title="${item.key}">${item.key}</td>
            <td class="px-4 py-3 text-sm text-gray-900 w-2/5 truncate" title="${item.original}">${item.original}</td>
            <td class="px-4 py-3">
                <input
                    type="text"
                    value="${item.translated}"
                    data-index="${index}"
                    class="translation-input w-full px-2 py-1 border rounded-md focus:ring-2 focus:ring-blue-500 truncate"
                    title="${item.translated}"
                    ${item.modified ? 'style="border-color: #4CAF50;"' : ''}
                >
            </td>
        `;
        tbody.appendChild(tr);
    });

    // 绑定输入事件
    document.querySelectorAll('.translation-input').forEach(input => {
        input.addEventListener('input', (e) => {
            resources[e.target.dataset.index].translated = e.target.value;
            resources[e.target.dataset.index].modified = true;
            e.target.style.borderColor = '#4CAF50';
        });
    });
}

// 翻译功能
document.getElementById('translate-btn').addEventListener('click', async () => {
    const loadingOverlay = document.getElementById('loading-overlay');
    loadingOverlay.classList.remove('hidden');
    
    try {
        const translationPromises = resources
            .filter(item => !item.translated || item.translated.trim() === '')
            .map(async item => {
                try {
                    item.translated = await translateText(item.original);
                } catch (error) {
                    console.error(`翻译失败 [${item.key}]:`, error);
                }
            });

        await Promise.all(translationPromises);
        renderTable();
    } catch (error) {
        console.error('翻译过程中发生错误:', error);
    } finally {
        loadingOverlay.classList.add('hidden');
    }
});

// 检查未翻译项
function checkUntranslated() {
    const untranslatedKeys = resources.filter(item => 
        !item.translated || item.translated.trim() === ''
    ).map(item => item.key);
    
    if (untranslatedKeys.length > 0) {
        // 标记未翻译项
        document.querySelectorAll('.translation-input').forEach(input => {
            if (!input.value.trim()) {
                input.style.borderColor = '#ff0000';
            }
        });
        return untranslatedKeys;
    }
    return null;
}

// 导出功能
document.getElementById('export-btn').addEventListener('click', async () => {
    const fileInput = document.getElementById('file-input');
    if (fileInput.files.length === 0) {
        alert('请先选择一个文件');
        return;
    }

    // 检查未翻译项
    const untranslatedKeys = checkUntranslated();
    if (untranslatedKeys) {
        const continueExport = confirm(`以下Key未翻译：\n${untranslatedKeys.join('\n')}\n\n点击"确定"继续导出，点击"取消"返回编辑`);
        if (!continueExport) return;
    }

    // 生成文件内容
    const newContent = generateTranslatedXAML();
    const blob = new Blob([newContent], { type: 'text/xaml' });
    
    try {
        // 使用更现代的文件保存API
        const handle = await window.showSaveFilePicker({
            suggestedName: fileInput.files[0].name.replace(/(\.xaml)?$/, '_en.xaml'),
            types: [
                {
                    description: 'XAML资源文件',
                    accept: {
                        'text/xaml': ['.xaml']
                    }
                }
            ],
            excludeAcceptAllOption: true // 强制用户选择文件类型
        });

        // 创建可写流并写入内容
        const writableStream = await handle.createWritable();
        await writableStream.write(blob);
        await writableStream.close();

        // 显示成功提示
        alert(`文件已成功保存到：\n${handle.name}`);
    } catch (err) {
        // 错误处理（用户取消或浏览器不支持）
        if (err.name !== 'AbortError') {
            const url = URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = fileInput.files[0].name.replace(/(\.xaml)?$/, '_en.xaml');
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
            URL.revokeObjectURL(url);
        }
    }
});

// 生成翻译后的XAML
function generateTranslatedXAML() {
    
    let output = `<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:sys="clr-namespace:System;assembly=mscorlib">\n`;

    resources.forEach(item => {
        output += `    <sys:String x:Key="${item.key}">${item.translated}</sys:String>\n`;
    });

    output += `</ResourceDictionary>`;
    return output;
}

// 启用/禁用按钮
function toggleButtons(enabled) {
    document.getElementById('translate-btn').disabled = !enabled;
    document.getElementById('export-btn').disabled = !enabled;
}

async function translateText(text) {
    const response = await fetch('http://localhost:3000/translate', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ text })
    });
    const data = await response.json();
    return data.trans_result[0].dst;
}

</script>
</body>
</html>
